/// ///************************************************************************
/// <copyrigth>2018-2019 Corporation.All Rights Reserved</copyrigth>
/// <author>tangyingzhong</author>
/// <contact>tangyz114987@outlook.com</contact>
/// <version>v1.0.0</version>
/// <describe>
/// Json file parser and write an json file by it
///</describe>
/// <date>2021/1/31</date>
///***********************************************************************
#ifndef JSONDOCUMENT_H
#define JSONDOCUMENT_H

#include <vector>
#include <string>
#include "json.h"

namespace SystemTool
{
	namespace IO
	{
		class JsonDocument
		{
		public:
			typedef Json::Value JsonObject;
			typedef Json::Reader JsonReader;
			typedef Json::ValueType ValueType;
			typedef std::string JsonString;
			typedef std::vector<JsonString> KeyTable;
			typedef unsigned int JsonSize;
			typedef unsigned int Index;

		public:
			// Construct the JsonDocument with json file
			JsonDocument();

			// Construct the JsonDocument with json object
			JsonDocument(JsonObject Value);

			// Detructe the JsonDocument
			~JsonDocument();

			// Copy the constructure
			JsonDocument(const JsonDocument& other);

			// Assign the object
			JsonDocument& operator=(const JsonDocument& other);

		public:
			// Json file to obejct 
			static JsonDocument FromJsonFile(JsonString strFilePath, JsonString& strErrorMsg);

			// String to object
			static JsonDocument FromJson(JsonString& strJson, JsonString& strErrorMsg);

			// To map
			void ToMap(std::map<std::string, std::string>& MapTable);

			// Object to string
			JsonString ToJson();

			// Get all keys
			bool GetKeys(KeyTable& FinalKeyTable);

			// Is contain the key
			bool IsContain(JsonString strKey);

			// Get array element
			JsonDocument operator[](Index iIndex);

			// Append the data
			JsonDocument& Append(JsonDocument JsonObject);

			// Append the data
			JsonDocument& Append(JsonString strValue);

			// Append the data
			JsonDocument& Append(int iValue);

			// Append the data
			JsonDocument& Append(double dValue);

			// Remove one element
			JsonDocument& RemoveAt(int iIndex);

			// Get the value of key
			JsonDocument GetKeyValue(JsonString strKey);

			// Set the key's value
			void SetKeyValue(JsonString strKey, JsonDocument& Doc);

			// Set the key's value
			void SetKeyValue(JsonString strKey, JsonString strValue);

			// Set the key's value
			void SetKeyValue(JsonString strKey, int iValue);

			// Set the key's value
			void SetKeyValue(JsonString strKey, double dValue);

			// Set the key's value
			void SetKeyValue(JsonString strKey, bool bIsBoolValue, bool bValue);

			// Set array
			void SetArray(JsonDocument& JsonDoc);

			// Size of the json object
			JsonSize Size();

			// Flush the json to file
			bool Flush(JsonString strFilePath);

			// To string
			JsonString ToString();

			// To int 
			int ToInt();

			// To double
			double ToDouble();

			// To bool
			bool ToBool();

			// Is the object null or not
			bool IsNull();

			// Is Obejct void
			bool IsEmpty();

			// Is Object
			bool IsObject();

			// Is the object bool value
			bool IsBool();

			// Is Double
			bool IsDouble();

			// Is the object int value
			bool IsInt();

			// Is the object string value
			bool IsString();

			// Is the object to be an array
			bool IsArray();

			// Get error message
			std::string GetErrorMsg();

		private:
			// Initialize the library
			void Initialize();

			// Destory the library
			void Destory();

			// Write the object to file
			bool WriteToFile(JsonString strFileName);

			// Get key's value
			JsonObject& Get(JsonString strKey);

			// Set the key's value
			void Set(JsonString strKey, JsonObject Value);

			// Parse the json file
			bool ParseFromFile(JsonString strJsonFilePath);

			// Parse from the string
			bool ParseFromData(std::string strData, JsonDocument& JsonDoc);

		private:
			// Get the JsonObject
			inline JsonObject& GetJsonObject()
			{
				return m_JsonObject;
			}

			// Set the JsonObject
			inline void SetJsonObject(JsonObject& Object)
			{
				m_JsonObject = Object;
			}

			// Set the disposed status
			inline void SetDisposed(bool bDisposed)
			{
				m_bDisposed = bDisposed;
			}

			// Get the disposed status
			inline bool GetDisposed() const
			{
				return m_bDisposed;
			}

			// Get the ErrorText
			inline std::string GetErrorText() const
			{
				return m_strErrorText;
			}

			// Set the ErrorText
			inline void SetErrorText(std::string strErrorText)
			{
				m_strErrorText = strErrorText;
			}

		private:
			// Json value
			JsonObject m_JsonObject;

			// Error message
			std::string m_strErrorText;

			// Disposed status
			bool m_bDisposed;
		};
	}
}

#endif // JSONDOCUMENT_H
